﻿using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace NFox.Pycad
{
    public static class DirectoryEx
    {

        public static void Init()
        {
            Location = new FileInfo(Assembly.GetExecutingAssembly().Location);
            Main = Location.Directory;
            StartFromMain = Main.Name == "main";
            if (StartFromMain)
            {
                Root = MainBackup = Main.Parent;
            }
            else
            {
                Root = Main;
                MainBackup = Main.CreateSubdirectory("main");
            }
            Plugins = Main.CreateSubdirectory("plugins");
            MainBackupPlugins = MainBackup.CreateSubdirectory("plugins");


            //如果从Main目录启动, 更新主目录文件
            if (StartFromMain)
            {
                foreach (var file in Main.GetFiles())
                    file.CopyTo(MainBackup.GetFileFullName(file.Name));
            }

            Bin = Root.CreateSubdirectory("bin");
            PythonLib = Bin.GetFile("Lib.zip");
            Support = Root.CreateSubdirectory("support");
            Extensions = Root.CreateSubdirectory("extensions");
            Stubs = Extensions.CreateSubdirectory(".stubs");
            Release = Extensions.CreateSubdirectory(".release");
            Scripts = Extensions.CreateSubdirectory(".scripts");
            Temp = Root.CreateSubdirectory("temp");
            Update = Root.CreateSubdirectory("update");
            Update.CreateSubdirectory("extensions");
        }

        public static bool StartFromMain { get; private set; }

        public static DirectoryInfo Main { get; private set; }

        public static DirectoryInfo MainBackup { get; private set; }

        public static FileInfo Location { get; private set; }

        public static DirectoryInfo Root { get; private set; }

        public static DirectoryInfo Bin { get; private set; }

        public static DirectoryInfo Plugins { get; private set; }

        public static DirectoryInfo MainBackupPlugins { get; private set; }

        public static DirectoryInfo Support { get; private set; }

        public static DirectoryInfo Extensions { get; private set; }

        public static DirectoryInfo Stubs { get; private set; }

        public static FileInfo PythonLib { get; private set; }

        public static DirectoryInfo Temp { get; private set; }

        public static DirectoryInfo Update { get; private set; }

        public static DirectoryInfo Release { get; private set; }

        public static DirectoryInfo Scripts { get; private set; }

        public static DirectoryInfo GetDirectory(Assembly assem)
        {
            return new FileInfo(assem.Location).Directory;
        }

        public static DirectoryInfo GetDirectory(this DirectoryInfo dir, string name)
        {
            var dirs = dir.GetDirectories(name);
            if (dirs.Length > 0)
                return dirs[0];
            return null;
        }

        public static DirectoryInfo GetDirectory(this DirectoryInfo dir, params string[] names)
        {
            foreach (var name in names)
            {
                if (dir != null)
                    dir = GetDirectory(dir, name);
                else
                    return null;
            }
            return dir;
        }

        public static FileInfo GetFile(this DirectoryInfo dir, params string[] names)
        {
            if (names.Length == 0)
                return null;
            int i = 0;
            for (; i< names.Length - 1; i++)
            {
                if (dir != null)
                    dir = GetDirectory(dir, names[i]);
                else
                    return null;
            }
            return dir.GetFile(names[i]);
        }

        public static FileInfo GetFile(this DirectoryInfo dir, string name)
        {
            var files = dir.GetFiles(name);
            if (files.Length > 0)
                return files[0];
            return null;
        }

        public static string GetFileFullName(this DirectoryInfo dir, string name)
        {
            return Path.Combine(dir.FullName, name);
        }

        public static List<FileInfo> GetAllFiles(this DirectoryInfo dir)
        {
            var files = new List<FileInfo>();
            GetAllFiles(dir, files);
            return files;
        }

        private static void GetAllFiles(this DirectoryInfo dir, List<FileInfo> files)
        {
            foreach (var d in dir.GetDirectories())
                GetAllFiles(d, files);
            foreach (var f in dir.GetFiles())
                files.Add(f);
        }

    }
}
